package dongshi.daddy;

import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.file.FileProps;
import io.vertx.core.file.FileSystem;
import io.vertx.core.http.HttpServer;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetServer;
import org.junit.Test;

public class VerxCoreHuohuo {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        System.out.println(vertx);

        // 指定配置项
        Vertx vertx11 = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40));
        System.out.println(vertx11);

        // 注意要添加对应的集群管理器依赖，详情见集群管理器章节 创建集群模式的 Vert.x 对象
        VertxOptions options = new VertxOptions();
        Vertx.clusteredVertx(options, res -> {
            if (res.succeeded()) {
                Vertx vertx22 = res.result(); // 获取到了集群模式下的 Vertx 对象
                // 做一些其他的事情
            } else {
                // 获取失败，可能是集群管理器出现了问题
            }
        });
    }

    // 使用vertx执行定时执行任务
    @Test
    public void timerWithVertx() throws Exception {
        Vertx vertx = Vertx.vertx();
        vertx.setPeriodic(1000, id -> {
            // 这个处理器将会每隔一秒被调用一次
            System.out.println("timer fired!");
        });
        Thread.sleep(999999);
    }

    @Test
    public void httpCall() throws Exception {
        Vertx vertx = Vertx.vertx();
        HttpServer server = vertx.createHttpServer();
        server.requestHandler(request -> {
            // 服务器每次收到一个HTTP请求时这个处理器将被调用
            request.response().end("hello world!!!");
        });

        // 监听端口9999
        server.listen(9999);
        Thread.sleep(999999);
    }

    // 获取文件大小
    @Test
    public void fileSizeTest() throws Exception {
        Vertx vertx = Vertx.vertx();
        FileSystem fs = vertx.fileSystem();
        Future<FileProps> future = fs.props("d:\\test\\starter.zip");
        future.onComplete((AsyncResult<FileProps> ar) -> {
            if (ar.succeeded()) {
                FileProps props = ar.result();
                System.out.println("File size = " + props.size());
            } else {
                System.out.println("Failure: " + ar.cause().getMessage());
            }
        });

        Thread.sleep(999999);
    }

    // 使用compose组合多个future，所有future都成功才算是成功
    @Test
    public void composeTest() throws Exception {
        Vertx vertx = Vertx.vertx();
        FileSystem fs = vertx.fileSystem();
        Future<Void> future = fs
                .createFile("d:\\test\\fff.txt")
                .compose(v -> {
                    // createFile文件创建完成后执行
                    return fs.writeFile("d:\\test\\fff.txt", Buffer.buffer("xxxxx"));
                })
                .compose(v -> {
                    // writeFile文件写入完成后执行
                    return fs.move("d:\\test\\fff.txt", "d:\\test\\starter");
                });

    }

    // 组合多个future，任意一个失败则失败
    @Test
    public void CompositeFutureTest() throws Exception {
        Vertx vertx = Vertx.vertx();
        HttpServer httpServer = vertx.createHttpServer();
        httpServer.requestHandler(request -> {
            // 服务器每次收到一个HTTP请求时这个处理器将被调用
            request.response().end("hello world!!!");
        });
        HttpServer netServer = vertx.createHttpServer();
        netServer.requestHandler(request -> {
            // 服务器每次收到一个HTTP请求时这个处理器将被调用
            request.response().end("hello world!!!!");
        });
        Future<HttpServer> httpServerFuture = httpServer.listen(8889);

        Future<HttpServer> netServerFuture = netServer.listen(9998);
        // 所有的成功才算是成功
        // 1：如果是希望其中一个成功就算是成功，则可以使用any方法
        // 2：如果是希望获取返回结果，则可以使用resultAt方法接受一个整数，和future的list一一对应
        // 3：如果是希望不论成功和失败所有的future都执行则可以使用join，虽然所有的future都会执行，但同all必须是所有的future都成功才算是成功，否则算是失败
        CompositeFuture.all(httpServerFuture, netServerFuture).onComplete(ar -> {
            if (ar.succeeded()) {
                // 所有服务器启动完成
                System.out.println("8889,9998全部监听成功");
            } else {
                // 有一个服务器启动失败
                System.out.println("yyyy");
            }
        });

        Thread.sleep(999999);
    }

    @Test
    public void verticleTest1() throws Exception {
        Vertx vertx = Vertx.vertx();
        //1: 如果是想利用多核提高并发性能，也可以部署多个verticle实例，如下：
        /*
        DeploymentOptions options = new DeploymentOptions().setInstances(16);
        vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
         */
        // 2:传入配置
        /*
        JsonObject config = new JsonObject().put("name", "tim").put("directory", "/blah");
        DeploymentOptions options = new DeploymentOptions().setConfig(config);
        vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

        获取配置：
        传入之后，这个配置可以通过 Context 对象或使用 config 方法访问。这个配置会以 JSON 对象（JsonObject）的形式返回， 因此您可以用下边代码读取数据：
        System.out.println("Configuration: " + config().getString("name"));
         */
        vertx.deployVerticle(new MyVerticle1(), res -> {
            if (res.succeeded()) {
                // 部署成功打印部署id，可以通过其来撤销部署，如下：
                /*
                vertx.undeploy(deploymentID, res -> {
                  if (res.succeeded()) {
                    System.out.println("Undeployed ok");
                  } else {
                    System.out.println("Undeploy failed!");
                  }
                });
                 */
                System.out.println("verticle 1 deploy suc, deploy id is: " + res.result());
            }
        });

        Thread.sleep(999999);
    }

    // 一次性计时器
    @Test
    public void timerTest1() throws Exception {
        Vertx vertx = Vertx.vertx();
        long timerID = vertx.setTimer(1000, id -> {
            System.out.println("And one second later this is printed");
        });
        System.out.println("First this is printed, timerID is: " + timerID);
        Thread.sleep(999999);
    }

    // 周期性计时器
    @Test
    public void timerTest2() throws Exception {
        Vertx vertx = Vertx.vertx();
        // 1：取消计时器 vertx.cancelTimer(timerID);
        // 2：如果您在 Verticle 中创建了计时器， 当这个 Verticle 被撤销时这个计时器会被自动关闭。
        long timerID = vertx.setPeriodic(1000, id -> {
            System.out.println("And every second this is printed");
        });
        System.out.println("First this is printed, timerID is: " + timerID);
        Thread.sleep(999999);
    }

    // 通过eventbus生产和发布消息
    @Test
    public void eventyBusTest() throws Exception {
        Vertx vertx = Vertx.vertx();
        // 订阅消息
        EventBus eb = vertx.eventBus();
        MessageConsumer<String> consumer = eb.consumer("news.uk.sport");
        // 1:带有确认的，可以像下边这样发送和接收消息
        /*
        接收者：
        MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");
        consumer.handler(message -> {
          System.out.println("I have received a message: " + message.body());
          message.reply("how interesting!");
        });
        发送者：

        eventBus.request("news.uk.sport", "Yay! Someone kicked a ball across a patch of grass", ar -> {
          if (ar.succeeded()) {
            System.out.println("Received reply: " + ar.result().body());
          }
        });
         */
        consumer.handler(message -> {
            System.out.println("I have received a message: " + message.body());
        });
        // 发布消息
        System.out.println("发布消息：" + "Yay! Someone kicked a ball");
        eb.publish("news.uk.sport", "Yay! Someone kicked a ball");
        Thread.sleep(999999);
    }

    // json支持测试
    @Test
    public void jsonTest() throws Exception {
        JsonObject object = new JsonObject();
        object.put("foo", "bar").put("num", 123).put("mybool", true);
        System.out.println(object.getInteger("num"));
    }

    private static Vertx vertx = Vertx.vertx();
    // tcp支持
    @Test
    public void tcpTest() {
        NetServer server = vertx.createNetServer();
        // 1：若想想要监听随机端口可以指定端口号为0，后续可以调用 actualPort 方法来获得服务器实际监听的端口
        // tcp server端
        server.listen(1234, "localhost", res -> {
            if (res.succeeded()) {
                System.out.println("Server is now listening!");
            } else {
                System.out.println("Failed to bind!");
            }
        });
    }
}



















